package sg.simple.snmp.provider.impl;

import isnmp.ui.dto.DeviceInfo;
import isnmp.ui.dto.DeviceInfo.DEVICE_PROPERTY;
import isnmp.ui.dto.NetworkInfo;
import isnmp.ui.dto.NetworkInfo.NETWORK_PROPERTY;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.util.TableEvent;

public class DeviceInfoProvider extends SNMPTableReader {

	/** Conceptual entry to mark the index in table */
	private String deviceIndexOid = "1.3.6.1.2.1.25.3.2.1.1";

	private String deviceDescOid = "1.3.6.1.2.1.25.3.2.1.3";

	private String deviceIdOid = "1.3.6.1.2.1.25.3.2.1.4";

	private String deviceStatusOid = "1.3.6.1.2.1.25.3.2.1.5";

	private String deviceErrorsOid = "1.3.6.1.2.1.25.3.2.1.6";

	static Map<String, String> statusCodes = new HashMap<String, String>();

	static {
		statusCodes.put("1", "unknown");
		statusCodes.put("2", "running");
		statusCodes.put("3", "warning");
		statusCodes.put("4", "testing");
		statusCodes.put("5", "down");

	}

	Logger logger = Logger.getLogger(NetworkInfoProvider.class);

	public List<DeviceInfo> retrieve(Snmp session, Target target) {

		OID deviceIndex = new OID(deviceIndexOid);
		OID deviceDesc = new OID(deviceDescOid);
		OID deviceId = new OID(deviceIdOid);
		OID deviceStatus = new OID(deviceStatusOid);
		OID deviceErrors = new OID(deviceErrorsOid);

		List<DeviceInfo> networkInformationList = new ArrayList<DeviceInfo>();

		List<TableEvent> networkInfoTable = this.readTable(session, target,
				new OID[] { deviceIndex, deviceDesc, deviceId, deviceStatus,
						deviceErrors });

		for (TableEvent aRow : networkInfoTable) {

			if (aRow.isError()) {
				continue;
			}

			String index = "";
			String desc = "";
			String id = "";
			String status = "";
			String errors = "";

			for (VariableBinding v : aRow.getColumns()) {

				if (matches(deviceIndex, v)) {
					index = v.getVariable().toString();
					continue;
				}

				if (matches(deviceDesc, v)) {
					desc = v.getVariable().toString();
					continue;
				}
				if (matches(deviceId, v)) {
					id = v.getVariable().toString();
					continue;
				}

				if (matches(deviceStatus, v)) {
					status = getDeviceStatus(v.getVariable().toString());

					continue;
				}

				if (matches(deviceErrors, v)) {
					errors = v.getVariable().toString();
					continue;
				}

			}

			DeviceInfo info = new DeviceInfo();
			info.putValue(DEVICE_PROPERTY.INDEX, index);
			info.putValue(DEVICE_PROPERTY.DESCRIPTION, desc);
			info.putValue(DEVICE_PROPERTY.ID, id);
			info.putValue(DEVICE_PROPERTY.STATUS, status);
			info.putValue(DEVICE_PROPERTY.ERRORS, errors);

			networkInformationList.add(info);
		}

		return networkInformationList;

	}

	private String getDeviceStatus(String code) {
		return statusCodes.get(code);
	}

}
